package admin

import (
	j_log "config-client-v1/init/j-log"
	"config-client-v1/model"
	"config-client-v1/utils/tools"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"gorm.io/gorm"
	"strings"
	"time"
)

// ModelDesc 各模型字段说明
func (con FSController) ModelDesc(ctx *gin.Context) {
	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
		"data": map[string]interface{}{
			"各模型字段说明": map[string]interface{}{
				"泵组电磁阀": model.BengzuModel{
					BengqianPressure: "泵前压力 AI",

					QianjibengStartControl: "前级泵-启动控制 DQ",
					QianjibengStopControl:  "前级泵-停止控制 DQ",
					QianjibengStartState:   "前级泵-启动状态 DI",
					QianjibengStopState:    "前级泵-停止状态 DI",
					LuocibengStartControl:  "罗茨泵-启动控制 DQ",
					LuocibengStopControl:   "罗茨泵-停止控制 DQ",
					LuocibengStartState:    "罗茨泵-启动状态 DI",
					LuocibengStopState:     "罗茨泵-停止状态 DI",
					BengqianStartControl:   "泵前电磁阀-启动控制 DQ",
					BengqianStopControl:    "泵前电磁阀-停止控制 DQ",
					BengqianStartState:     "泵前电磁阀-启动状态 DI",
					BengqianStopState:      "泵前电磁阀-停止状态 DI",

					BengzuStartControl:      "泵组控制-启动控制, 有字段就行, 不用管字段值, 创建模型后自动就有地址了. 如有需要在下面字段填值",
					BengzuStartControlValue: 0,
					BengzuStopControl:       "泵组控制-停止控制, 有字段就行, 不用管字段值, 创建模型后自动就有地址了. 如有需要在下面字段填值",
					BengzuStopControlValue:  0,
					BengzuStartState:        "泵组控制-启动状态, 有字段就行, 不用管字段值, 创建模型后自动就有地址了. 如有需要在下面字段填值",
					BengzuStartStateValue:   0,
					BengzuStopState:         "泵组控制-启动控制, 停止状态, 不用管字段值, 创建模型后自动就有地址了. 如有需要在下面字段填值",
					BengzuStopStateValue:    0,

					BengzuParam1:      "泵组控制-参数1, 不用管字段值, 创建模型后自动就有地址了. 如有需要在下面字段填值",
					BengzuParam1Value: 3.14,
					BengzuParam2:      "泵组控制-参数2, 不用管字段值, 创建模型后自动就有地址了. 如有需要在下面字段填值",
					BengzuParam2Value: 3.14,
					BengzuParam3:      "泵组控制-参数3, 不用管字段值, 创建模型后自动就有地址了. 如有需要在下面字段填值",
					BengzuParam3Value: 3.14,
					BengzuParam4:      "泵组控制-参数4, 不用管字段值, 创建模型后自动就有地址了. 如有需要在下面字段填值",
					BengzuParam4Value: 3.14,
					BengzuParam5:      "泵组控制-参数5, 不用管字段值, 创建模型后自动就有地址了. 如有需要在下面字段填值",
					BengzuParam5Value: 3.14,

					RemoteLocal:        "远程就地, 不用管字段值, 创建模型后自动就有地址了. 如有需要在下面字段填值",
					RemoteLocalValue:   1,
					Liansuo:            "连锁,不用管字段值, 创建模型后自动就有地址了. 如有需要在下面字段填值",
					LiansuoValue:       1,
					ControlMethod:      "控制方法, 不用管字段值, 创建模型后自动就有地址了. 如有需要在下面字段填值",
					ControlMethodValue: 1,
				},
				"增压泵电磁阀": model.ZengyaModel{
					BengqianPressure: "泵前压力 AI",

					BengqianStartControl: "泵前电磁阀-启动控制 DQ",
					BengqianStopControl:  "泵前电磁阀-停止控制 DQ",
					BengqianStartState:   "泵前电磁阀-启动状态 DI",
					BengqianStopState:    "泵前电磁阀-停止状态 DI",

					ZengyaStartControl: "增压泵-启动控制 DQ",
					ZengyaStopControl:  "增压泵-停止控制 DQ",
					ZengyaStartState:   "增压泵-启动状态 DI",
					ZengyaStopState:    "增压泵-停止状态 DI",

					RemoteLocal:        "远程就地, 不用管字段值, 创建模型后自动就有地址了. 如有需要在下面字段填值",
					RemoteLocalValue:   1,
					Liansuo:            "连锁,不用管字段值, 创建模型后自动就有地址了. 如有需要在下面字段填值",
					LiansuoValue:       1,
					ControlMethod:      "控制方法, 不用管字段值, 创建模型后自动就有地址了. 如有需要在下面字段填值",
					ControlMethodValue: 1,
				},
				"电调阀": model.DiantiaoSVModel{
					CurrentKaidu:       "当前开度 AI",
					SetKaidu:           "设置开度 AQ",
					Control:            "控制 DQ",
					SetStep:            "设置步长 AQ",
					SelfInspection:     "自检控制 DQ",
					Up:                 "上调 DQ",
					Down:               "下调 DQ",
					AllOn:              "全开 DQ",
					AllOff:             "全关 DQ",
					AllOnState:         "全开状态 DI",
					AllOffState:        "全关状态 DI",
					QianjiPressure:     "前级压力 AI",
					HoujiPressure:      "后级压力 AI",
					DestPressure:       "目标压力 AQ",
					P:                  "P AQ",
					I:                  "I AQ",
					D:                  "D AQ",
					CustomStartControl: "自整定-启动控制 DQ",
					CustomStopControl:  "自整定-停止控制 DQ",
					CustomStartState:   "自整定-启动状态 DI",
					CustomStopState:    "自整定-停止状态 DI",
					Custom:             "自整定 ??? excel文档中没有这个字段",
					PID:                "PID DQ",
					RemoteLocal:        "远程就地 DQ",
					ControlMethod:      "控制方法 AQ",
				},
				"压力电磁阀": model.PressureSVModel{
					Liansuo:            "连锁,不用管字段值, 创建模型后自动就有地址了. 如有需要在下面字段填值",
					LiansuoValue:       1,
					ControlMethod:      "控制方法, 不用管字段值, 创建模型后自动就有地址了. 如有需要在下面字段填值",
					ControlMethodValue: 1,
				},
				"电源控制": model.PowerModel{
					PLCType:      1,
					IP:           "192.168.1.1",
					Port:         502,
					U1BlockValue: 0,
					U1AddrValue:  "0",
					U1Addr:       "U2变量地址-从第三方PLC选择过来的变量地址, 选择后自动带入上面的块和地址",
					U2BlockValue: 65535,
					U2AddrValue:  "0.1",
					U2Addr:       "U2变量地址-从第三方PLC选择过来的变量地址, 选择后自动带入上面的块和地址",
				},
				"电源状态模型": model.PowerStateModel{
					RunningStateBlockValue: 0,
					RunningStateAddr:       "运行状态地址-变量地址, 新增自动生成, 只读不可修改,需要回显, 下面带value的是预设值",
					RunningStateType:       4,
					RunningStateAddrValue:  "40.15",
					ErrorStateType:         0,
					ErrorStateBlockValue:   0,
					ErrorStateAddr:         "故障状态地址-变量地址, 新增自动生成, 只读不可修改,需要回显, 下面带value的是预设值",
					ErrorStateAddrValue:    "0",
				},
				"模态采集": model.ModeCollectModel{
					StimulatePoint: "激励点位 AI",
					ResponsePoint:  "响应点位 AI",
					StartControl:   "开控制 DQ",
					StopControl:    "关控制 DQ",
					StartState:     "开状态 DI",
					StopState:      "关状态 DI",
				},
				"故障诊断": model.DiagModel{
					DiagMode: "本模型所有字段, 不用管字段值, 创建模型后自动就有地址了. 如有需要在下面字段填值",
				},
			},
		},
	})
}

// ModelList 模型列表
func (con FSController) ModelList(ctx *gin.Context) {
	userToken := GetUserToken(ctx)
	param := struct {
		FSID       int    `json:"fs_id"`
		ModuleType string `json:"module_type"`
	}{}
	err := ctx.ShouldBindBodyWith(&param, binding.JSON)
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数",
			"data":    err.Error(),
		})
		return
	}
	if param.ModuleType != "" {
		_, ok := model.AllowFSCode2[param.ModuleType]
		if !ok {
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "无效的参数 module_type",
				"data":    "",
			})
			return
		}
	}
	fsIds := make([]int, 0)
	err = model.DB.Model(&model.FSEquip{}).Where("project_id = ?", userToken.ProjectID).Pluck("id", &fsIds).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}

	tx := model.DB.Model(&model.FSModel{}).
		Where("fs_id in ?", fsIds).
		Where("code2 in ?", []string{"05", "06", "07", "08", "09", "10", "13", "14"})
	if param.ModuleType != "" {
		tx.Where("module_type = ?", param.ModuleType)
	}
	if param.FSID != 0 {
		tx.Where("fs_id = ?", param.FSID)
	}

	list := make([]*model.FSModel, 0)
	err = tx.Preload("FSEquipInfo").Order("id ASC").Offset(0).Limit(5000).Find(&list).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	for _, row := range list {
		if row.FSEquipInfo != nil {
			row.FSName = row.FSEquipInfo.Name
			row.FSEquipInfo = nil
		}
		switch row.ModuleType {
		case "泵组电磁阀":
			content := model.BengzuModel{}
			_ = json.Unmarshal([]byte(row.JsonDetail), &content)
			row.Content = content
		case "增压泵电磁阀":
			content := model.ZengyaModel{}
			_ = json.Unmarshal([]byte(row.JsonDetail), &content)
			row.Content = content
		case "电调阀":
			content := model.DiantiaoSVModel{}
			_ = json.Unmarshal([]byte(row.JsonDetail), &content)
			row.Content = content
		case "压力电磁阀":
			content := model.PressureSVModel{}
			_ = json.Unmarshal([]byte(row.JsonDetail), &content)
			row.Content = content
		case "电源控制":
			content := model.PowerModel{}
			_ = json.Unmarshal([]byte(row.JsonDetail), &content)
			row.Content = content
		case "电源状态":
			content := model.PowerStateModel{}
			_ = json.Unmarshal([]byte(row.JsonDetail), &content)
			row.Content = content
		case "模态采集":
			content := model.ModeCollectModel{}
			_ = json.Unmarshal([]byte(row.JsonDetail), &content)
			row.Content = content
		case "故障诊断":
			content := model.DiagModel{}
			_ = json.Unmarshal([]byte(row.JsonDetail), &content)
			row.Content = content
		}
		row.JsonDetail = ""
	}

	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
		"data": map[string]interface{}{
			"list": list,
		},
	})
}

// ModelSave 模型保存
func (con FSController) ModelSave(ctx *gin.Context) {
	userToken := GetUserToken(ctx)
	param := struct {
		ID         int    `json:"id"`
		FSID       int    `json:"fs_id"`                                // 自研设备ID
		ModuleType string `json:"module_type" binding:"max=30"`         // 模型类型就等于code2 , 05-14
		Content    string `json:"content" binding:"required,max=20000"` // 模型内容 json字符串格式
	}{}
	err0 := ctx.ShouldBindBodyWith(&param, binding.JSON)
	if err0 != nil {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数",
			"data":    err0.Error(),
		})
		return
	}
	now := tools.GetNow()
	if param.ID == 0 {
		fse := &model.FSEquip{}
		exist, err := fse.Exists(param.FSID) // 判断 fs_id 是否有效
		if !exist {
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "无效的参数 fs_id",
				"data":    err,
			})
			return
		}
		code2, ok := model.AllowModelCode2[param.ModuleType] // 判断 module_type 是否有效
		if !ok {
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "无效的参数 module_type",
				"data": map[string]interface{}{
					"module_type": model.AllowModelCode2,
				},
			})
			return
		}
		code1 := fse.Code1 // code1
		usedCode3 := make([]string, 0)
		err = model.DB.Model(&model.FSModule{}).Where("fs_id = ? AND code2 = ?", param.FSID, code2).Pluck("code3", &usedCode3).Error
		if err != nil {
			ctx.JSON(200, gin.H{
				"code":    6,
				"message": err.Error(),
			})
			return
		}
		availableCode3 := model.GetAvailableCode(model.AllCode3FS(), usedCode3)
		if len(availableCode3) < 1 {
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "可用的模型序号不足, code3不足",
				"data": map[string]interface{}{
					"code": code1 + "-" + code2,
				},
			})
		}
		code3 := availableCode3[0] // 准备新增的模型序号 code3
		data := &model.FSModule{}
		data.ProjectID = userToken.ProjectID
		data.Code1 = code1
		data.Code2 = code2
		data.Code3 = code3
		data.FSID = param.FSID
		data.ModuleType = param.ModuleType
		data.ModuleName = param.ModuleType + code3
		data.CreateTime = &now
		data.UpdateTime = &now

		//list := getFSModelFieldList(param.ModuleType)
		list := make([]*model.FrameItem, 0)
		switch param.ModuleType {
		case "泵组电磁阀":
			content := &model.BengzuModel{}
			err = json.Unmarshal([]byte(param.Content), content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": "json解析失败 content",
					"data":    err.Error(),
				})
				return
			}
			list, err = model.ValidateFSModelContent(userToken.ProjectID, content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": err.Error(),
				})
				return
			}
			err = model.DB.Transaction(func(tx *gorm.DB) error {
				err = tx.Omit("FrameItem").Create(&data).Error
				if err != nil {
					return err
				}
				/*--- 创建变量地址,自动生成变量地址 ---*/
				err = model.FSModelFrameItemHandle(list, data, userToken.ProjectID)
				if err != nil {
					return err
				}
				if len(list) > 0 {
					err = tx.Create(&list).Error
					if err != nil {
						return err
					}
				}
				model.FillFrameAddrToBengzuModel(list, content)
				jsonB, _ := json.Marshal(content)
				data.JsonDetail = string(jsonB)
				err = tx.Model(&model.FSModule{}).Where("id = ?", data.ID).Update("json_detail", string(jsonB)).Error
				if err != nil {
					return err
				}
				return nil
			})
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    10,
					"message": err.Error(),
				})
				return
			}
		case "增压泵电磁阀":
			content := &model.ZengyaModel{}
			err = json.Unmarshal([]byte(param.Content), content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": "json解析失败 content",
					"data":    err.Error(),
				})
				return
			}
			list, err = model.ValidateFSModelContent(userToken.ProjectID, content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": err.Error(),
				})
				return
			}
			err = model.DB.Transaction(func(tx *gorm.DB) error {
				err = tx.Omit("FrameItem").Create(&data).Error
				if err != nil {
					return err
				}
				/*--- 创建变量地址,自动生成变量地址 ---*/
				err = model.FSModelFrameItemHandle(list, data, userToken.ProjectID)
				if err != nil {
					return err
				}
				err = tx.Create(&list).Error
				if err != nil {
					return err
				}
				model.FillFrameAddrToZengyaModel(list, content)
				jsonB, _ := json.Marshal(content)
				data.JsonDetail = string(jsonB)
				err = tx.Model(&model.FSModule{}).Where("id = ?", data.ID).Update("json_detail", string(jsonB)).Error
				if err != nil {
					return err
				}
				return nil
			})
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    10,
					"message": err.Error(),
				})
				return
			}
		case "电调阀":
			content := &model.DiantiaoSVModel{}
			err = json.Unmarshal([]byte(param.Content), content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": "json解析失败 content",
					"data":    err.Error(),
				})
				return
			}
			list, err = model.ValidateFSModelContent(userToken.ProjectID, content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": err.Error(),
				})
				return
			}
			jsonB, _ := json.Marshal(content)
			data.JsonDetail = string(jsonB)
			err = model.DB.Omit("FrameItem").Create(&data).Error
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    6,
					"message": err.Error(),
				})
				return
			}
		case "压力电磁阀":
			content := &model.PressureSVModel{}
			err = json.Unmarshal([]byte(param.Content), content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": "json解析失败 content",
					"data":    err.Error(),
				})
				return
			}
			list, err = model.ValidateFSModelContent(userToken.ProjectID, content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": err.Error(),
				})
				return
			}
			err = model.DB.Transaction(func(tx *gorm.DB) error {
				err = tx.Omit("FrameItem").Create(&data).Error
				if err != nil {
					return err
				}
				/*--- 创建变量地址,自动生成变量地址 ---*/
				err = model.FSModelFrameItemHandle(list, data, userToken.ProjectID)
				if err != nil {
					return err
				}
				err = tx.Create(&list).Error
				if err != nil {
					return err
				}
				model.FillFrameAddrToPressureModel(list, content)
				jsonB, _ := json.Marshal(content)
				data.JsonDetail = string(jsonB)
				err = tx.Model(&model.FSModule{}).Where("id = ?", data.ID).Update("json_detail", string(jsonB)).Error
				if err != nil {
					return err
				}
				return nil
			})
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    10,
					"message": err.Error(),
				})
				return
			}
		case "电源控制":
			content := &model.PowerModel{}
			err = json.Unmarshal([]byte(param.Content), content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": "json解析失败 content",
					"data":    err.Error(),
				})
				return
			}
			_, err = model.ValidateFSModelContent(userToken.ProjectID, content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": err.Error(),
				})
				return
			}
			jsonB, _ := json.Marshal(content)
			data.JsonDetail = string(jsonB)
			err = model.DB.Transaction(func(tx *gorm.DB) error {
				err = tx.Omit("FrameItem").Create(&data).Error
				if err != nil {
					return err
				}
				return nil
			})
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    10,
					"message": err.Error(),
				})
				return
			}
		case "电源状态":
			content := &model.PowerStateModel{}
			err = json.Unmarshal([]byte(param.Content), content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": "json解析失败 content",
					"data":    err.Error(),
				})
				return
			}
			_, err = model.ValidateFSModelContent(userToken.ProjectID, content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": err.Error(),
				})
				return
			}
			jsonB, _ := json.Marshal(content)
			data.JsonDetail = string(jsonB)
			err = model.DB.Transaction(func(tx *gorm.DB) error {
				err = tx.Omit("FrameItem").Create(&data).Error
				if err != nil {
					return err
				}
				return nil
			})
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    10,
					"message": err.Error(),
				})
				return
			}
		case "模态采集":
			content := &model.ModeCollectModel{}
			err = json.Unmarshal([]byte(param.Content), content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": "json解析失败 content",
					"data":    err.Error(),
				})
				return
			}
			list, err = model.ValidateFSModelContent(userToken.ProjectID, content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": err.Error(),
				})
				return
			}
			jsonB, _ := json.Marshal(content)
			data.JsonDetail = string(jsonB)
			err = model.DB.Omit("FrameItem").Create(&data).Error
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    6,
					"message": err.Error(),
				})
				return
			}
		case "故障诊断":
			content := &model.DiagModel{}
			err = json.Unmarshal([]byte(param.Content), content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": "json解析失败 content",
					"data":    err.Error(),
				})
				return
			}
			list, err = model.ValidateFSModelContent(userToken.ProjectID, content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": err.Error(),
				})
				return
			}
			err = model.DB.Transaction(func(tx *gorm.DB) error {
				err = tx.Omit("FrameItem").Create(&data).Error
				if err != nil {
					return err
				}
				/*--- 创建变量地址,自动生成变量地址 ---*/
				err = model.FSModelFrameItemHandle(list, data, userToken.ProjectID)
				if err != nil {
					return err
				}
				err = tx.Create(&list).Error
				if err != nil {
					return err
				}
				model.FillFrameAddrToDiagModel(list, content)
				jsonB, _ := json.Marshal(content)
				data.JsonDetail = string(jsonB)
				err = tx.Model(&model.FSModule{}).Where("id = ?", data.ID).Update("json_detail", string(jsonB)).Error
				if err != nil {
					return err
				}
				return nil
			})
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    10,
					"message": err.Error(),
				})
				return
			}
		default:
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "暂不支持此 module_type",
				"data":    "",
			})
			return
		}
	} else { // --------------------修改
		fse := &model.FSModule{}
		exist, err := fse.Exists(param.ID)
		if !exist {
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "无效的参数 id",
				"data":    err,
			})
			return
		}
		list := make([]*model.FrameItem, 0)
		var tmpModel interface{}
		switch fse.ModuleType {
		case "泵组电磁阀":
			content := &model.BengzuModel{}
			err = json.Unmarshal([]byte(param.Content), content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": "json解析失败 content",
					"data":    err.Error(),
				})
				return
			}
			list, err = model.ValidateFSModuleContentCombo(userToken.ProjectID, fse, content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    15,
					"message": err.Error(),
					"data":    map[string]interface{}{},
				})
				return
			}
			model.FillFrameAddrToBengzuModel(list, content)
			tmpModel = content
		case "增压泵电磁阀":
			content := &model.ZengyaModel{}
			err = json.Unmarshal([]byte(param.Content), content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": "json解析失败 content",
					"data":    err.Error(),
				})
				return
			}
			list, err = model.ValidateFSModuleContentCombo(userToken.ProjectID, fse, content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    15,
					"message": err.Error(),
					"data":    map[string]interface{}{},
				})
				return
			}
			model.FillFrameAddrToZengyaModel(list, content)
			tmpModel = content
		case "电调阀":
			content := &model.DiantiaoSVModel{}
			err = json.Unmarshal([]byte(param.Content), content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": "json解析失败 content",
					"data":    err.Error(),
				})
				return
			}
			tmpModel = content
		case "压力电磁阀":
			content := &model.PressureSVModel{}
			err = json.Unmarshal([]byte(param.Content), content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": "json解析失败 content",
					"data":    err.Error(),
				})
				return
			}
			list, err = model.ValidateFSModuleContentCombo(userToken.ProjectID, fse, content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    15,
					"message": err.Error(),
					"data":    map[string]interface{}{},
				})
				return
			}
			model.FillFrameAddrToPressureModel(list, content)
			tmpModel = content
		case "电源控制":
			content := &model.PowerModel{}
			err = json.Unmarshal([]byte(param.Content), content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": "json解析失败 content",
					"data":    err.Error(),
				})
				return
			}
			list, err = model.ValidateFSModuleContentCombo(userToken.ProjectID, fse, content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    15,
					"message": err.Error(),
					"data":    map[string]interface{}{},
				})
				return
			}
			tmpModel = content
		case "电源状态":
			content := &model.PowerStateModel{}
			err = json.Unmarshal([]byte(param.Content), content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": "json解析失败 content",
					"data":    err.Error(),
				})
				return
			}
			list, err = model.ValidateFSModuleContentCombo(userToken.ProjectID, fse, content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    15,
					"message": err.Error(),
					"data":    map[string]interface{}{},
				})
				return
			}
			tmpModel = content
		case "模态采集":
			content := &model.ModeCollectModel{}
			err = json.Unmarshal([]byte(param.Content), content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": "json解析失败 content",
					"data":    err.Error(),
				})
				return
			}
			tmpModel = content
		case "故障诊断":
			content := &model.DiagModel{}
			err = json.Unmarshal([]byte(param.Content), content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": "json解析失败 content",
					"data":    err.Error(),
				})
				return
			}
			list, err = model.ValidateFSModuleContentCombo(userToken.ProjectID, fse, content)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    15,
					"message": err.Error(),
					"data":    map[string]interface{}{},
				})
				return
			}
			model.FillFrameAddrToDiagModel(list, content)
			tmpModel = content
		default:
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "暂不支持此 module_type",
				"data":    "",
			})
			return
		}

		data := &model.FSModule{}
		jsonB, _ := json.Marshal(tmpModel)
		data.JsonDetail = string(jsonB)
		data.UpdateTime = &now
		err = model.DB.Model(&model.FSModule{}).Where("id = ?", param.ID).Select("json_detail", "update_time").Updates(&data).Error
		if err != nil {
			ctx.JSON(200, gin.H{
				"code":    6,
				"message": err.Error(),
			})
			return
		}
	}
	err := model.SyncFSEquipToMem(param.FSID)
	if err != nil {
		j_log.LogWarning([]interface{}{"SyncFSEquipToMem 同步内存数据失败", err})
	}
	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
		"data":    map[string]interface{}{},
	})
}

// ModelDelete 模型删除
func (con FSController) ModelDelete(ctx *gin.Context) {
	param := struct {
		ModuleID int `json:"module_id" binding:"required"`
	}{}
	err := ctx.ShouldBindBodyWith(&param, binding.JSON)
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数",
			"data":    err.Error(),
		})
		return
	}
	info := model.FSModule{}
	err = model.DB.Where("id = ?", param.ModuleID).Limit(1).Find(&info).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	_, ok := model.AllowModelCode2[info.ModuleType]
	if !ok {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数 module_id",
		})
		return
	}
	if info.ID == 0 {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数 module_id",
			"data":    "",
		})
		return
	}

	err = model.DB.Transaction(func(tx *gorm.DB) error {
		err = tx.Where("id = ?", param.ModuleID).Delete(&model.FSModule{}).Error
		if err != nil {
			return err
		}
		err = tx.Where("module_id = ?", param.ModuleID).Delete(&model.FrameItem{}).Error
		if err != nil {
			return err
		}
		return nil
	})
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    10,
			"message": err.Error(),
		})
		return
	}
	err = model.SyncFSEquipToMem(info.FSID)
	if err != nil {
		j_log.LogWarning([]interface{}{"SyncFSEquipToMem 同步内存数据失败", err})
	}

	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
		"data":    map[string]interface{}{},
	})
}

// ModelDownload 模型下载 功能码 03
func (con FSController) ModelDownload(ctx *gin.Context) {
	userToken := GetUserToken(ctx)
	param := struct {
		FSID         int    `json:"fs_id" binding:"required"`
		ModuleType   string `json:"module_type" binding:"required,max=20"`
		ModuleNumber int    `json:"module_number" binding:"required"`
	}{}
	err := ctx.ShouldBindBodyWith(&param, binding.JSON)
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数",
			"data":    err.Error(),
		})
		return
	}
	fse, ok := model.RunningFSMap.Get(param.FSID)
	if !ok {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "FS设备TCP未连接",
			"data":    map[string]interface{}{},
		})

		_ = model.CommandHistoryLog(3, userToken.ProjectID, param.FSID, param.ModuleType+"模型下载", fmt.Sprintf("%s%02d下载", param.ModuleType, param.ModuleNumber), "admin/fs/model_download", param, 1, "FS设备TCP未连接")
		return
	}
	if fse.RunningState != 2 {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "FS设备TCP未连接",
			"data":    map[string]interface{}{},
		})
		_ = model.CommandHistoryLog(3, userToken.ProjectID, param.FSID, param.ModuleType+"模型下载", fmt.Sprintf("%s%02d下载", param.ModuleType, param.ModuleNumber), "admin/fs/model_download", param, 1, "FS设备TCP未连接")
		return
	}

	data := make([]byte, 0)
	switch strings.ToUpper(param.ModuleType) {
	case "泵组电磁阀":
		data, err = model.GenFSModuleData0301(fse, fmt.Sprintf("%02d", param.ModuleNumber))
	case "增压泵电磁阀":
		data, err = model.GenFSModuleData0302(fse, fmt.Sprintf("%02d", param.ModuleNumber))
	case "电调阀":
		data, err = model.GenFSModuleData0303(fse, fmt.Sprintf("%02d", param.ModuleNumber))
	case "压力电磁阀":
		data, err = model.GenFSModuleData0304(fse, fmt.Sprintf("%02d", param.ModuleNumber))
	case "电源控制":
		data, err = model.GenFSModuleData0305(fse, fmt.Sprintf("%02d", param.ModuleNumber))
	case "电源状态":
		data, err = model.GenFSModuleData0306(fse, fmt.Sprintf("%02d", param.ModuleNumber))
	case "模态采集":
		data, err = model.GenFSModuleData0307(fse, fmt.Sprintf("%02d", param.ModuleNumber))
	case "故障诊断":
		data, err = model.GenFSModuleData0308(fse, fmt.Sprintf("%02d", param.ModuleNumber))
	default:
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数",
			"data":    param.ModuleType,
		})
		return
	}
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    1,
			"message": err.Error(),
		})
		return
	}

	_ = tools.WriteStringToLog(fmt.Sprintf("[%s~%s]【send】len=%d#%s", tools.GetNow(), fse.TcpClient.RemoteAddr, len(data), tools.ByteArrayToHexStr(data)), "model_download.log", "a")

	_, err = fse.Write(data)
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "发送失败",
			"data":    err.Error(),
		})
		_ = model.CommandHistoryLog(3, userToken.ProjectID, param.FSID, param.ModuleType+"模型下载", fmt.Sprintf("%s%02d下载", param.ModuleType, param.ModuleNumber), "admin/fs/model_download", param, 1, "发送失败")
		return
	}

	tcpRequest := model.NewFSTCPRequest()
	key := time.Now().UnixNano()
	fse.TcpClient.Requests.Set(key, tcpRequest)
	defer fse.TcpClient.Requests.Delete(key)

	hex := ""
	success := true
	select {
	case hex = <-tcpRequest.Resp0301:
		success = true
	case hex = <-tcpRequest.Resp0381:
		success = false
	case hex = <-tcpRequest.Resp0302:
		success = true
	case hex = <-tcpRequest.Resp0382:
		success = false
	case hex = <-tcpRequest.Resp0303:
		success = true
	case hex = <-tcpRequest.Resp0383:
		success = false
	case hex = <-tcpRequest.Resp0304:
		success = true
	case hex = <-tcpRequest.Resp0384:
		success = false
	case hex = <-tcpRequest.Resp0305:
		success = true
	case hex = <-tcpRequest.Resp0385:
		success = false
	case hex = <-tcpRequest.Resp0306:
		success = true
	case hex = <-tcpRequest.Resp0386:
		success = false
	case hex = <-tcpRequest.Resp0307:
		success = true
	case hex = <-tcpRequest.Resp0387:
		success = false
	case hex = <-tcpRequest.Resp0308:
		success = true
	case hex = <-tcpRequest.Resp0388:
		success = false
	case <-time.After(3 * time.Second):
		ctx.JSON(200, gin.H{
			"code":    1,
			"message": "下载超时",
			"data": map[string]interface{}{
				"req": tools.ByteArrayToHexStr(data),
			},
		})
		_ = model.CommandHistoryLog(3, userToken.ProjectID, param.FSID, param.ModuleType+"模型下载", fmt.Sprintf("%s%02d下载", param.ModuleType, param.ModuleNumber), "admin/fs/model_download", param, 1, "下载超时")
		return
	}
	if success {
		ctx.JSON(200, gin.H{
			"code":    0,
			"message": "下载成功",
			"data": map[string]interface{}{
				"req":  tools.ByteArrayToHexStr(data),
				"resp": hex,
			},
		})
		_ = model.CommandHistoryLog(3, userToken.ProjectID, param.FSID, param.ModuleType+"模型下载", fmt.Sprintf("%s%02d下载", param.ModuleType, param.ModuleNumber), "admin/fs/model_download", param, 0, "下载成功")

	} else {
		ctx.JSON(200, gin.H{
			"code":    1,
			"message": "下载失败",
			"data": map[string]interface{}{
				"req":  tools.ByteArrayToHexStr(data),
				"resp": hex,
			},
		})
		_ = model.CommandHistoryLog(3, userToken.ProjectID, param.FSID, param.ModuleType+"模型下载", fmt.Sprintf("%s%02d下载", param.ModuleType, param.ModuleNumber), "admin/fs/model_download", param, 1, "下载失败")
	}

}

// ModelUpload 模型上载
func (con FSController) ModelUpload(ctx *gin.Context) {
	userToken := GetUserToken(ctx)
	param := struct {
		FSID         int    `json:"fs_id" binding:"required"`              // FS设备ID
		ModuleType   string `json:"module_type" binding:"required,max=20"` // 模型类型
		ModuleNumber uint8  `json:"module_number"`                         // 模型序号
		Debug        uint8  `json:"debug"`                                 // 如果为1则不执行模型基本信息读取校验
	}{}
	err := ctx.ShouldBindBodyWith(&param, binding.JSON)
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数",
			"data":    err.Error(),
		})
		return
	}
	if param.ModuleNumber == 0 {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "序号不可为0",
			"data":    "",
		})
		return
	}
	_, ok := model.AllowModelCode2[param.ModuleType]
	if !ok {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数 module_type",
			"data": map[string]interface{}{
				"可选范围": model.AllowModelCode2,
			},
		})
		return
	}
	code3 := fmt.Sprintf("%02d", param.ModuleNumber)
	fse, ok := model.RunningFSMap.Get(param.FSID)
	if !ok {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "FS设备TCP未连接",
			"data":    map[string]interface{}{},
		})
		_ = model.CommandHistoryLog(5, userToken.ProjectID, param.FSID, param.ModuleType+"模型上载", param.ModuleType+code3+"上载", "admin/fs/model_upload", param, 1, "FS设备TCP未连接")
		return
	}

	if fse.RunningState != 2 {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "FS设备TCP未连接",
			"data":    map[string]interface{}{},
		})
		_ = model.CommandHistoryLog(5, userToken.ProjectID, param.FSID, param.ModuleType+"模型上载", param.ModuleType+code3+"上载", "admin/fs/model_upload", param, 1, "FS设备TCP未连接")
		return
	}

	fseTmp, ok := model.TempFSMap.Get(param.FSID)
	if !ok {
		if param.Debug == 1 {
			fseTmp = &model.FSEquip{}
			fseTmp.DS = &model.DataScale{}
			fseTmp.DSModuleRead = 1
			model.TempFSMap.Set(param.FSID, fseTmp)
		} else {
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "请先读取控制模型基本信息",
				"data":    map[string]interface{}{},
			})
			return
		}
	}
	if fseTmp.DSModelRead == 0 {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "请先读取控制模型基本信息",
			"data":    map[string]interface{}{},
		})
		return
	}

	var moduleQuantity uint8
	data := []byte{0x5A, 0x05, 0x02, 0xCC, 0xCC}
	switch strings.ToUpper(param.ModuleType) {
	case "泵组电磁阀":
		moduleQuantity = fseTmp.DS.Bengzu
		data[2] = 0x02 // 指令码修改
	case "增压泵电磁阀":
		moduleQuantity = fseTmp.DS.Zengya
		data[2] = 0x03
	case "电调阀":
		moduleQuantity = fseTmp.DS.Diantiao
		data[2] = 0x04
	case "压力电磁阀":
		moduleQuantity = fseTmp.DS.Pressure
		data[2] = 0x05
	case "电源控制":
		moduleQuantity = fseTmp.DS.Power
		data[2] = 0x06
	case "电源状态":
		moduleQuantity = fseTmp.DS.PowerState
		data[2] = 0x07
	case "模态采集":
		moduleQuantity = fseTmp.DS.ModeCollect
		data[2] = 0x08
	case "故障诊断":
		moduleQuantity = fseTmp.DS.Diag
		data[2] = 0x09
	default:
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数",
			"data":    param.ModuleType,
		})
		return
	}
	if moduleQuantity == 0 {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "模型数量为0",
			"data":    map[string]interface{}{},
		})
		return
	}
	if param.ModuleNumber > moduleQuantity {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "模型序号超出数据规模范围",
			"data": map[string]interface{}{
				"模型总数": moduleQuantity,
				"模型序号": param.ModuleNumber,
			},
		})
		return
	}
	data = append(data, moduleQuantity, param.ModuleNumber)
	data = append(data, 0x00, 0x00, 0x00, 0x00, 0xA5)
	model.FixDataLength(fse, data)
	_, err = fse.Write(data)
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "发送失败",
			"data":    err.Error(),
		})
		_ = model.CommandHistoryLog(5, userToken.ProjectID, param.FSID, param.ModuleType+"模型上载", param.ModuleType+code3+"上载", "admin/fs/model_upload", param, 1, "发送失败")
		return
	}

	tcpRequest := model.NewFSTCPRequest()
	key := time.Now().UnixNano()
	fse.TcpClient.Requests.Set(key, tcpRequest)
	defer fse.TcpClient.Requests.Delete(key)
	success := true
	hex := ""
	select {
	case hex = <-tcpRequest.Resp0502:
		success = true
	case hex = <-tcpRequest.Resp0582:
		success = false
	case hex = <-tcpRequest.Resp0503:
		success = true
	case hex = <-tcpRequest.Resp0583:
		success = false
	case hex = <-tcpRequest.Resp0504:
		success = true
	case hex = <-tcpRequest.Resp0584:
		success = false
	case hex = <-tcpRequest.Resp0505:
		success = true
	case hex = <-tcpRequest.Resp0585:
		success = false
	case hex = <-tcpRequest.Resp0506:
		success = true
	case hex = <-tcpRequest.Resp0586:
		success = false
	case hex = <-tcpRequest.Resp0507:
		success = true
	case hex = <-tcpRequest.Resp0587:
		success = false
	case hex = <-tcpRequest.Resp0508:
		success = true
	case hex = <-tcpRequest.Resp0588:
		success = false
	case hex = <-tcpRequest.Resp0509:
		success = true
	case hex = <-tcpRequest.Resp0589:
		success = false
	case <-time.After(3 * time.Second):
		ctx.JSON(200, gin.H{
			"code":    1,
			"message": "上载超时",
			"data": map[string]interface{}{
				"req": tools.ByteArrayToHexStr(data),
			},
		})
		_ = model.CommandHistoryLog(5, userToken.ProjectID, param.FSID, param.ModuleType+"模型上载", param.ModuleType+code3+"上载", "admin/fs/model_upload", param, 1, "上载超时")
		return
	}

	if success {
		ctx.JSON(200, gin.H{
			"code":    0,
			"message": "上载成功",
			"data": map[string]interface{}{
				"req":  tools.ByteArrayToHexStr(data),
				"resp": hex,
			},
		})
		_ = model.CommandHistoryLog(5, userToken.ProjectID, param.FSID, param.ModuleType+"模型上载", param.ModuleType+code3+"上载", "admin/fs/model_upload", param, 0, "上载成功")

	} else {
		ctx.JSON(200, gin.H{
			"code":    1,
			"message": "上载失败",
			"data": map[string]interface{}{
				"req":  tools.ByteArrayToHexStr(data),
				"resp": hex,
			},
		})
		_ = model.CommandHistoryLog(5, userToken.ProjectID, param.FSID, param.ModuleType+"模型上载", param.ModuleType+code3+"上载", "admin/fs/model_upload", param, 1, "上载失败")
	}
}

func (con FSController) ModelUploadApiList(ctx *gin.Context) {
	param := struct {
		FSID int `json:"fs_id" binding:"required"`
	}{}
	err := ctx.ShouldBindBodyWith(&param, binding.JSON)
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数",
			"data":    err.Error(),
		})
		return
	}

	fse, ok := model.RunningFSMap.Get(param.FSID)
	if !ok {
		ctx.JSON(200, gin.H{
			"code":    1,
			"message": "FS设备TCP未连接",
			"data":    map[string]interface{}{},
		})
		return
	}
	if fse.RunningState != 2 {
		ctx.JSON(200, gin.H{
			"code":    1,
			"message": "FS设备TCP未连接",
			"data":    map[string]interface{}{},
		})
		return
	}

	tempFSE, ok := model.TempFSMap.Get(param.FSID)
	if !ok {
		ctx.JSON(200, gin.H{
			"code":    1,
			"message": "请先读取控制模型基本信息~",
			"data":    map[string]interface{}{},
		})
		return
	}
	if tempFSE.DSModelRead == 0 {
		ctx.JSON(200, gin.H{
			"code":    1,
			"message": "请先读取控制模型基本信息~half",
			"data":    map[string]interface{}{},
		})
		return
	}

	list := make([]*DownloadApi, 0)
	putFSModelUploadAPI(tempFSE, &list, "泵组电磁阀", tempFSE.DS.Bengzu)
	putFSModelUploadAPI(tempFSE, &list, "增压泵电磁阀", tempFSE.DS.Zengya)
	putFSModelUploadAPI(tempFSE, &list, "电调阀", tempFSE.DS.Diantiao)
	putFSModelUploadAPI(tempFSE, &list, "压力电磁阀", tempFSE.DS.Pressure)
	putFSModelUploadAPI(tempFSE, &list, "电源控制", tempFSE.DS.Power)
	putFSModelUploadAPI(tempFSE, &list, "电源状态", tempFSE.DS.PowerState)
	putFSModelUploadAPI(tempFSE, &list, "模态采集", tempFSE.DS.ModeCollect)
	putFSModelUploadAPI(tempFSE, &list, "故障诊断", tempFSE.DS.Diag)

	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
		"data": map[string]interface{}{
			"list": list,
		},
	})
}

// ModelUpdateAddrEV 已废弃, 改用 UpdateEV
func (con FSController) ModelUpdateAddrEV(ctx *gin.Context) {
	userToken := GetUserToken(ctx)
	projectID := userToken.ProjectID
	param := struct {
		ModuleID int    `json:"module_id" binding:"required"`
		Position string `json:"Position" binding:"required,max=20"`
		/*
			泵组电磁阀: [前级泵,罗茨泵,泵前电磁阀,泵组控制]
			增压泵电磁阀: [泵前电磁阀,增压泵]
			电调阀: [自整定]
			压力电磁阀: [电磁阀]
			模态采集: [控制]
		*/
		Content string `json:"content" binding:"required,max=20000"` // 模型内容 json字符串格式
	}{}
	err := ctx.ShouldBindBodyWith(&param, binding.JSON)
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数",
			"data":    err.Error(),
		})
		return
	}
	fsm := &model.FSModule{}
	exist, err := fsm.Exists(param.ModuleID)
	if !exist {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数 module_id",
			"data":    err,
		})
		return
	}
	var contentNew any
	var jsonB []byte
	now := tools.GetNow()
	switch fsm.ModuleType {
	case "泵组电磁阀":
		content := &model.BengzuModel{}
		err = json.Unmarshal([]byte(param.Content), content)
		if err != nil {
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "json解析失败 content",
				"data":    err.Error(),
			})
			return
		}
		contentOld := &model.BengzuModel{}
		err = json.Unmarshal([]byte(fsm.JsonDetail), contentOld)
		if err != nil {
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "json解析失败 fsm.JsonDetail",
				"data":    err.Error(),
			})
			return
		}
		switch param.Position {
		case "前级泵":
			contentOld.QianjibengStartControl = content.QianjibengStartControl
			contentOld.QianjibengStopControl = content.QianjibengStopControl
			contentOld.QianjibengStartState = content.QianjibengStartState
			contentOld.QianjibengStopState = content.QianjibengStopState
			if !model.CheckAddrSpecType(projectID, content.QianjibengStartControl, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.QianjibengStartControl),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.QianjibengStopControl, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.QianjibengStopControl),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.QianjibengStartState, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.QianjibengStartState),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.QianjibengStopState, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.QianjibengStopState),
				})
				return
			}
			contentOld.QianjibengStartControlEV = content.QianjibengStartControlEV
			contentOld.QianjibengStopControlEV = content.QianjibengStopControlEV
			contentOld.QianjibengStartStateEV = content.QianjibengStartStateEV
			contentOld.QianjibengStopStateEV = content.QianjibengStopStateEV
		case "罗茨泵":
			contentOld.LuocibengStartControl = content.LuocibengStartControl
			contentOld.LuocibengStopControl = content.LuocibengStopControl
			contentOld.LuocibengStartState = content.LuocibengStartState
			contentOld.LuocibengStopState = content.LuocibengStopState
			if !model.CheckAddrSpecType(projectID, content.LuocibengStartControl, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.LuocibengStartControl),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.LuocibengStopControl, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.LuocibengStopControl),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.LuocibengStartState, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.LuocibengStartState),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.LuocibengStopState, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.LuocibengStopState),
				})
				return
			}
			contentOld.LuocibengStartControlEV = content.LuocibengStartControlEV
			contentOld.LuocibengStopControlEV = content.LuocibengStopControlEV
			contentOld.LuocibengStartStateEV = content.LuocibengStartStateEV
			contentOld.LuocibengStopStateEV = content.LuocibengStopStateEV
		case "泵前电磁阀":
			contentOld.BengqianStartControl = content.BengqianStartControl
			contentOld.BengqianStopControl = content.BengqianStopControl
			contentOld.BengqianStartState = content.BengqianStartState
			contentOld.BengqianStopState = content.BengqianStopState
			if !model.CheckAddrSpecType(projectID, content.BengqianStartControl, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.BengqianStartControl),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.BengqianStopControl, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.BengqianStopControl),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.BengqianStartState, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.BengqianStartState),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.BengqianStopState, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.BengqianStopState),
				})
				return
			}

			contentOld.BengqianStartControlEV = content.BengqianStartControlEV
			contentOld.BengqianStopControlEV = content.BengqianStopControlEV
			contentOld.BengqianStartStateEV = content.BengqianStartStateEV
			contentOld.BengqianStopStateEV = content.BengqianStopStateEV
		case "泵组控制":
			contentOld.BengzuStartControl = content.BengzuStartControl
			contentOld.BengzuStopControl = content.BengzuStopControl
			contentOld.BengzuStartState = content.BengzuStartState
			contentOld.BengzuStopState = content.BengzuStopState
			if !model.CheckAddrSpecType(projectID, content.BengzuStartControl, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.BengzuStartControl),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.BengzuStopControl, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.BengzuStopControl),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.BengzuStartState, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.BengzuStartState),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.BengzuStopState, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.BengzuStopState),
				})
				return
			}

			contentOld.BengzuStartControlEV = content.BengzuStartControlEV
			contentOld.BengzuStopControlEV = content.BengzuStopControlEV
			contentOld.BengzuStartStateEV = content.BengzuStartStateEV
			contentOld.BengzuStopStateEV = content.BengzuStopStateEV
		default:
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "参数无效 position:" + param.Position,
			})
			return
		}
		contentNew = contentOld
	case "增压泵电磁阀":
		content := &model.ZengyaModel{}
		err = json.Unmarshal([]byte(param.Content), content)
		if err != nil {
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "json解析失败 content",
				"data":    err.Error(),
			})
			return
		}
		contentOld := &model.ZengyaModel{}
		err = json.Unmarshal([]byte(fsm.JsonDetail), contentOld)
		if err != nil {
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "json解析失败 fsm.JsonDetail",
				"data":    err.Error(),
			})
			return
		}
		switch param.Position {
		case "泵前电磁阀":
			contentOld.BengqianStartControl = content.BengqianStartControl
			contentOld.BengqianStopControl = content.BengqianStopControl
			contentOld.BengqianStartState = content.BengqianStartState
			contentOld.BengqianStopState = content.BengqianStopState
			if !model.CheckAddrSpecType(projectID, content.BengqianStartControl, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.BengqianStartControl),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.BengqianStopControl, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.BengqianStopControl),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.BengqianStartState, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.BengqianStartState),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.BengqianStopState, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.BengqianStopState),
				})
				return
			}

			contentOld.BengqianStartControlEV = content.BengqianStartControlEV
			contentOld.BengqianStopControlEV = content.BengqianStopControlEV
			contentOld.BengqianStartStateEV = content.BengqianStartStateEV
			contentOld.BengqianStopStateEV = content.BengqianStopStateEV
		case "增压泵":
			contentOld.ZengyaStartControl = content.ZengyaStartControl
			contentOld.ZengyaStopControl = content.ZengyaStopControl
			contentOld.ZengyaStartState = content.ZengyaStartState
			contentOld.ZengyaStopState = content.ZengyaStopState
			if !model.CheckAddrSpecType(projectID, content.ZengyaStartControl, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.ZengyaStartControl),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.ZengyaStopControl, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.ZengyaStopControl),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.ZengyaStartState, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.ZengyaStartState),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.ZengyaStopState, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.ZengyaStopState),
				})
				return
			}

			contentOld.ZengyaStartControlEV = content.ZengyaStartControlEV
			contentOld.ZengyaStopControlEV = content.ZengyaStopControlEV
			contentOld.ZengyaStartStateEV = content.ZengyaStartStateEV
			contentOld.ZengyaStopStateEV = content.ZengyaStopStateEV
		default:
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "参数无效 position:" + param.Position,
			})
			return
		}
		contentNew = contentOld
	case "电调阀":
		content := &model.DiantiaoSVModel{}
		err = json.Unmarshal([]byte(param.Content), content)
		if err != nil {
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "json解析失败 content",
				"data":    err.Error(),
			})
			return
		}
		contentOld := &model.DiantiaoSVModel{}
		err = json.Unmarshal([]byte(fsm.JsonDetail), contentOld)
		if err != nil {
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "json解析失败 fsm.JsonDetail",
				"data":    err.Error(),
			})
			return
		}
		switch param.Position {
		case "自整定":
			contentOld.CustomStartControl = content.CustomStartControl
			contentOld.CustomStopControl = content.CustomStopControl
			contentOld.CustomStartState = content.CustomStartState
			contentOld.CustomStopState = content.CustomStopState
			if !model.CheckAddrSpecType(projectID, content.CustomStartControl, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.CustomStartControl),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.CustomStopControl, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.CustomStopControl),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.CustomStartState, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.CustomStartState),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.CustomStopState, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.CustomStopState),
				})
				return
			}

			contentOld.CustomStartControlEV = content.CustomStartControlEV
			contentOld.CustomStopControlEV = content.CustomStopControlEV
			contentOld.CustomStartStateEV = content.CustomStartStateEV
			contentOld.CustomStopStateEV = content.CustomStopStateEV
		default:
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "参数无效 position:" + param.Position,
			})
			return
		}
		contentNew = contentOld
	case "压力电磁阀":
		content := &model.PressureSVModel{}
		err = json.Unmarshal([]byte(param.Content), content)
		if err != nil {
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "json解析失败 content",
				"data":    err.Error(),
			})
			return
		}
		contentOld := &model.PressureSVModel{}
		err = json.Unmarshal([]byte(fsm.JsonDetail), contentOld)
		if err != nil {
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "json解析失败 fsm.JsonDetail",
				"data":    err.Error(),
			})
			return
		}
		switch param.Position {
		case "电磁阀":
			contentOld.SVStartControl = content.SVStartControl
			contentOld.SVStopControl = content.SVStopControl
			contentOld.SVStartState = content.SVStartState
			contentOld.SVStopState = content.SVStopState
			if !model.CheckAddrSpecType(projectID, content.SVStartControl, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.SVStartControl),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.SVStopControl, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.SVStopControl),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.SVStartState, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.SVStartState),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.SVStopState, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.SVStopState),
				})
				return
			}

			contentOld.SVStartControlEV = content.SVStartControlEV
			contentOld.SVStopControlEV = content.SVStopControlEV
			contentOld.SVStartStateEV = content.SVStartStateEV
			contentOld.SVStopStateEV = content.SVStopStateEV
		default:
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "参数无效 position:" + param.Position,
			})
			return
		}
		contentNew = contentOld
	case "电源控制":
		content := &model.PowerModel{}
		err = json.Unmarshal([]byte(param.Content), content)
		if err != nil {
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "json解析失败 content",
				"data":    err.Error(),
			})
			return
		}
	case "电源状态":
		content := &model.PowerStateModel{}
		err = json.Unmarshal([]byte(param.Content), content)
		if err != nil {
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "json解析失败 content",
				"data":    err.Error(),
			})
			return
		}
	case "模态采集":
		content := &model.ModeCollectModel{}
		err = json.Unmarshal([]byte(param.Content), content)
		if err != nil {
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "json解析失败 content",
				"data":    err.Error(),
			})
			return
		}
		contentOld := &model.ModeCollectModel{}
		err = json.Unmarshal([]byte(fsm.JsonDetail), contentOld)
		if err != nil {
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "json解析失败 fsm.JsonDetail",
				"data":    err.Error(),
			})
			return
		}
		switch param.Position {
		case "控制":
			contentOld.StartControl = content.StartControl
			contentOld.StopControl = content.StopControl
			contentOld.StartState = content.StartState
			contentOld.StopState = content.StopState
			if !model.CheckAddrSpecType(projectID, content.StartControl, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.StartControl),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.StopControl, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.StopControl),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.StartState, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.StartState),
				})
				return
			}
			if !model.CheckAddrSpecType(projectID, content.StopState, "uint8") {
				ctx.JSON(200, gin.H{
					"code":    2,
					"message": fmt.Sprintf("FS%s-%s%s-%s 变量地址类型错误 %s", fsm.Code1, fsm.ModuleType, fsm.Code3, param.Position, content.StopState),
				})
				return
			}

			contentOld.StartControlEV = content.StartControlEV
			contentOld.StopControlEV = content.StopControlEV
			contentOld.StartStateEV = content.StartStateEV
			contentOld.StopStateEV = content.StopStateEV
		default:
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "参数无效 position:" + param.Position,
			})
			return
		}
		contentNew = contentOld

	case "故障诊断":
		content := &model.DiagModel{}
		err = json.Unmarshal([]byte(param.Content), content)
		if err != nil {
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "json解析失败 content",
				"data":    err.Error(),
			})
			return
		}

	default:
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "暂不支持此模型" + fsm.ModuleType,
		})
		return
	}

	jsonB, _ = json.Marshal(contentNew)
	fsm.JsonDetail = string(jsonB)
	fsm.UpdateTime = &now
	err = model.DB.Model(&model.FSModule{}).Where("id = ?", param.ModuleID).Select("json_detail", "update_time").Updates(fsm).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}

	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
		"data":    map[string]interface{}{},
	})
}

func (con FSController) ModelPLCImport(ctx *gin.Context) {
	userToken := GetUserToken(ctx)
	projectID := userToken.ProjectID
	param := struct {
		PLCType    uint8  `json:"plc_type"`    // [1.西门子 2.AB 3.汇川 4.信捷 5.和利时 6.三菱 7.欧姆龙]
		IP         string `json:"ip"`          // IP地址
		Port       uint16 `json:"port"`        // 端口
		ModuleType string `json:"module_type"` // 默认 电源控制, 电源状态
	}{}
	err := ctx.ShouldBindBodyWith(&param, binding.JSON)
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数",
			"data":    err.Error(),
		})
		return
	}
	if param.ModuleType == "" {
		param.ModuleType = "电源控制"
	}
	if !tools.IsValidIP(param.IP) {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的IP地址",
		})
		return
	}
	ppeList := make([]*model.PPE, 0)
	err = model.DB.Where("project_id = ? AND protocol_name = ?", projectID, "PLC").Find(&ppeList).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": "查询sql失败",
			"data":    err.Error(),
		})
		return
	}
	config := model.PLCConfig{}
	ppe := &model.PPE{}
	matched := false
	switch param.PLCType {
	case 1:
		for _, row := range ppeList {
			if row.Mode == "S7-1200" || row.Mode == "S7-1500" {
				err = json.Unmarshal([]byte(row.Config), &config)
				if err != nil {
					ctx.JSON(200, gin.H{
						"code":    6,
						"message": "json解析失败 PLCConfig",
						"data":    err.Error(),
					})
					return
				}
				//fmt.Printf("config:plc_type=%v,ip=%v,port=%v; b1=%v,b2=%v\n", config.Type, config.IP, config.Port, config.IP == param.IP, uint16(config.Port) == param.Port)
				if config.IP == param.IP && uint16(config.Port) == param.Port {
					matched = true
					ppe = row
					break
				}
			}
		}
		if !matched {
			ctx.JSON(200, gin.H{
				"code":    1,
				"message": "未找到匹配的第三方PLC设备",
				"data":    map[string]interface{}{},
			})
			return
		}
	case 3:
		for _, row := range ppeList {
			if row.Mode == "汇川" {
				err = json.Unmarshal([]byte(row.Config), &config)
				if err != nil {
					ctx.JSON(200, gin.H{
						"code":    6,
						"message": "json解析失败 PLCConfig",
						"data":    err.Error(),
					})
					return
				}
				if config.IP == param.IP && uint16(config.Port) == param.Port {
					matched = true
					ppe = row
					break
				}
			}
		}
		if !matched {
			ctx.JSON(200, gin.H{
				"code":    1,
				"message": "未找到匹配的第三方PLC设备",
				"data":    map[string]interface{}{},
			})
			return
		}
	default:
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "暂不支持此PLC类型",
		})
		return
	}

	frameList := make([]*model.Frame, 0)
	err = model.DB.Where("ppe_id = ?", ppe.ID).Find(&frameList).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": "查询sql失败",
			"data":    err.Error(),
		})
		return
	}

	switch param.ModuleType {
	case "电源控制":
		content := &model.PowerModel{}
		content.PLCType = param.PLCType
		content.IP = param.IP
		content.Port = param.Port
		for _, frame := range frameList {
			frameParamList := make([]*model.FrameItemParam, 0)
			err = json.Unmarshal([]byte(frame.JsonDetail), &frameParamList)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    6,
					"message": "json解析失败 FrameItemParam",
					"data":    err.Error(),
				})
			}
			for _, item := range frameParamList {
				if item.FieldName == "U1" {
					content.U1Addr = item.Addr
					content.U1Type, content.U1BlockValue, content.U1AddrValue = GetPlcTypeValue(content.PLCType, frame, item)
				}
				if item.FieldName == "U2" {
					content.U2Addr = item.Addr
					content.U2Type, content.U2BlockValue, content.U2AddrValue = GetPlcTypeValue(content.PLCType, frame, item)
				}
				if item.FieldName == "U3" {
					content.U3Addr = item.Addr
					content.U3Type, content.U3BlockValue, content.U3AddrValue = GetPlcTypeValue(content.PLCType, frame, item)
				}
				if item.FieldName == "I1" {
					content.I1Addr = item.Addr
					content.I1Type, content.I1BlockValue, content.I1AddrValue = GetPlcTypeValue(content.PLCType, frame, item)
				}
				if item.FieldName == "I2" {
					content.I2Addr = item.Addr
					content.I2Type, content.I2BlockValue, content.I2AddrValue = GetPlcTypeValue(content.PLCType, frame, item)
				}
				if item.FieldName == "I3" {
					content.I3Addr = item.Addr
					content.I3Type, content.I3BlockValue, content.I3AddrValue = GetPlcTypeValue(content.PLCType, frame, item)
				}

				if item.FieldName == "F" {
					content.FAddr = item.Addr
					content.FType, content.FBlockValue, content.FAddrValue = GetPlcTypeValue(content.PLCType, frame, item)
				}
				if item.FieldName == "有功功率" {
					content.ActivePowerAddr = item.Addr
					content.ActivePowerType, content.ActivePowerBlockValue, content.ActivePowerAddrValue = GetPlcTypeValue(content.PLCType, frame, item)
				}
				if item.FieldName == "无功功率" {
					content.ReactivePowerAddr = item.Addr
					content.ReactivePowerType, content.ReactivePowerBlockValue, content.ReactivePowerAddrValue = GetPlcTypeValue(content.PLCType, frame, item)
				}
				if item.FieldName == "视在功率" {
					content.ApparentPowerAddr = item.Addr
					content.ApparentPowerType, content.ApparentPowerBlockValue, content.ApparentPowerAddrValue = GetPlcTypeValue(content.PLCType, frame, item)
				}

			}
		}

		ctx.JSON(200, gin.H{
			"code":    0,
			"message": "success",
			"data": map[string]interface{}{
				"content": content,
			},
		})
	case "电源状态":
		content := &model.PowerStateModel{}
		content.PLCType = param.PLCType
		content.IP = param.IP
		content.Port = param.Port
		for _, frame := range frameList {
			frameParamList := make([]*model.FrameItemParam, 0)
			err = json.Unmarshal([]byte(frame.JsonDetail), &frameParamList)
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    6,
					"message": "json解析失败 FrameItemParam",
					"data":    err.Error(),
				})
			}

			for _, item := range frameParamList {
				if item.FieldName == "运行状态" {
					content.RunningStateAddr = item.Addr
					content.RunningStateType, content.RunningStateBlockValue, content.RunningStateAddrValue = GetPlcTypeValue(content.PLCType, frame, item)
				}
				if item.FieldName == "故障状态" {
					content.ErrorStateAddr = item.Addr
					content.ErrorStateType, content.ErrorStateBlockValue, content.ErrorStateAddrValue = GetPlcTypeValue(content.PLCType, frame, item)
				}
			}

		}
		ctx.JSON(200, gin.H{
			"code":    0,
			"message": "success",
			"data": map[string]interface{}{
				"content": content,
			},
		})

	default:
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "暂不支持此模型" + param.ModuleType,
		})
		return
	}

}

/*
GetPlcTypeValue 获取PLC类型值
real： 01
int8： 02
int16：03
bool： 04
*/
func GetPlcTypeValue(plcType uint8, frame *model.Frame, item *model.FrameItemParam) (t uint8, block uint16, addrValue string) {
	switch item.SpecType {
	case "uint8":
		fallthrough
	case "int8":
		t = 2
	case "uint16":
		fallthrough
	case "int16":
		t = 3
	case "uint32":
	case "int32":
	case "uint64":
	case "int64":
	case "float32":
		fallthrough
	case "float64":
		t = 1
	case "bool":
		t = 4
	}
	addrInteger := frame.StartAddr + uint16(item.Start)
	addrFloat := item.BoolBits
	if t == 4 {
		addrValue = tools.AddrJoin(addrInteger, addrFloat)
	} else {
		addrValue = fmt.Sprintf("%d", addrInteger)
	}
	switch plcType {
	case 1:
		block = uint16(frame.DBNumber)
	case 3:
		block = uint16(frame.SlaveID)
	}
	return
}
